package com.google.code.solrdimension.config;

import java.util.ArrayList;
import java.util.List;

import com.google.code.solrdimension.config.dimension.DimensionConfig;
import com.google.code.solrdimension.config.dimensionvalue.AbstractDimensionValueConfig;
import com.google.code.solrdimension.core.DimensionInputDocument;

/**
 * 
 * The main configuration object for SolrDimension
 * 
 * 
 * 
 * @author Michael Chan
 * 
 */
public class DimensionConfigWrapper {

    /**
     * An arraylist of dimension config, basically contents in the element from
     * the SolrDimension XML configuration file
     */
    private List<DimensionConfig> dimensionConfigs;

    /**
     * {@link XmlConfigurationService} will add the solr field name
     * to this arraylist. The purpose of this is to avoid loops over all
     * dimensionConfigs object from the {@link DimensionInputDocument}
     */
    private List<String> solrFieldsToModify = new ArrayList<String>();

    /**
     * 
     * @return - An ArrayList of String contiaining all Solr fields that
     *         SolrDimension would modify
     */
    public List<String> getSolrFieldsToModify() {
        return solrFieldsToModify;
    }

    /**
     * Adds a new entry to the SolrFieldsToModify arraylist
     * 
     * @param solrFieldToModify
     */
    public void addSolrFieldToModify(String solrFieldToModify) {
        this.solrFieldsToModify.add(solrFieldToModify);
    }

    /**
     * 
     * @return An ArrayList of {@link DimensionConfig}
     */
    public List<DimensionConfig> getDimensionConfigs() {
        return dimensionConfigs;
    }

    /**
     * Mutator, sets the internal dimensionConfigs
     * 
     * @param dimensionConfigs
     */
    public void setDimensionConfigs(List<DimensionConfig> dimensionConfigs) {
        this.dimensionConfigs = dimensionConfigs;
    }

    /**
     * Returns all {@link DimensionConfig} in the dimensionConfs list containing
     * the filed provided in solrField
     * 
     * 
     * @param solrField
     * @param getManualConfigOnly
     *            if true, retrieves only the DimensionConfig with typ = manual;
     *            if = true, then retrieves all DimensionConfig with the
     *            matching solrfield
     *            
     * @return
     *          A List of {@link DimensionConfig} 
     *          
     * TODO: Consider using ehcache for this method
     */
    public List<DimensionConfig> getDimensionConfigsBySolrField(String solrField, boolean getManualConfigOnly) {

        List<DimensionConfig> dimensionConfigs = null;

        if (solrField != null && !solrField.isEmpty()) {
            for (DimensionConfig dimConfig : this.dimensionConfigs) {
                
                if (solrField.equals(dimConfig.getSolrFieldName())) {
                   
                    if (dimensionConfigs == null) {
                        dimensionConfigs = new ArrayList<DimensionConfig>();
                    }
                    
                    //Add a manual type
                    if (DimensionConfig.TYPE_MANUAL.equals(dimConfig.getType())) {

                        dimensionConfigs.add(dimConfig);

                    } else if (!getManualConfigOnly){
                        
                        //getManualConfigOnly is set to false, now also add the default Dim config type
                        dimensionConfigs.add(dimConfig);
                    }
                   
                }

            }

        }

        return dimensionConfigs;
    }
    
    /**
     * Retrieves the {@link DimensionConfig} ids with the DimensionValue IDs
     * 
     * @param dimensionValueId 
     * @return
     *          An ArrayList of {@link DimensionConfig} id 
     *          
     *          
     * TODO: Consider caching this with ehcache
     */      
    public ArrayList<String> getSelectedDimensionConfigs(String[] dimensionValueIds) {
        
        ArrayList<String> dimensionConfigIds = new ArrayList<String>();       
        if (dimensionValueIds != null && dimensionValueIds.length > 0){
            
            for (DimensionConfig dimensionConfig : this.dimensionConfigs){
                
                for (AbstractDimensionValueConfig dimensionValueConfig : dimensionConfig.getDimensionValueConfigs()){
                    
                    boolean matchFound = false;
                    
                    for (int i=0; i < dimensionValueIds.length; i++){
                        
                        if (dimensionValueConfig.getDimensionValueId().equals(dimensionValueIds[i])){
                            matchFound = true;
                            dimensionConfigIds.add(dimensionConfig.getId());
                            //Exit the loop now
                            break;
                        }
                        
                    }
                    
                    //if there is a matched dimensionValue with the given  dimensionValueId, we can break 
                    //the dimensionValueConfig loop, since we know that the dimension is already selected
                    if (matchFound){
                        break;
                    }
                    
                }
                
            }
            
        }
        
        return dimensionConfigIds;
        
    }
    
    
}
